package com.shg.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.criterion.Projections;
import org.springframework.stereotype.Service;

import com.shg.bean.Book;
import com.shg.bean.BookType;
import com.shg.service.BookTypeService;

@Service
public class BookTypeServiceBean extends BasiceDaoImpl<BookType> implements BookTypeService {

	private Map<String, BookType> map;
	//用来存储顶级类
	private Set<String> keys;
	//
	private List<BookType> childs=new ArrayList<BookType>();
	/**
	 * 获取店铺的书籍类型
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Set<BookType> getShopBookType(String shopid){
		List<BookType> list = sessionFactory.getCurrentSession().createCriteria(Book.class)
			.setProjection(Projections.projectionList()
					.add(Projections.groupProperty("parent").as("parent"))
					).list();
		List<String> parent=new ArrayList<String>();
		for(int i=0;i<list.size();i++){
			parent.add(list.get(i).getId());
		}
		if(list!=null){
			return  getTypeList(parent);
		}
		return null;
	}
	/**
	 * 采用逆向思维解决该问题
	 * 调用该方法将会传入一个字符串数组，然后根据ID查询所有的对象
	 * 查询的采用顺藤摸瓜的方式查询，把查询出来的数据放在map数组里面
	 * @param types
	 */
	public Set<BookType> getTypeList(List<String> types){
		map=new HashMap<String, BookType>();
		keys=new HashSet<String>();
		
		Set<BookType> bookTypes=new HashSet<BookType>();
		for(String id:types){
			//查询但前的类型
			BookType currentType = (BookType) sessionFactory.getCurrentSession().get(BookType.class, id);
			map.put(currentType.getId(), currentType);
			//检查其是否存在父类
			String parentid=currentType.getParent()==null?null:currentType.getParent().getId();
			if(parentid!=null && !parentid.equals("")){//如果存在父类
				if(map.get(parentid)!=null){
					map.get(parentid).getTypes().add(currentType);
				}else{
					getRecursion(parentid,currentType);
				}
			}else{//如果不存在父类，将其添加到map集合里面，并将其键添加到keys字符串数组里面
				keys.add(currentType.getId());
			}
		}
		//这里获得到的全是顶级的BookType
		for(String id:keys){
			bookTypes.add(map.get(id));
		}
		return bookTypes;
	}
	/**
	 * 递归查询
	 * @param id父类的ID
	 * @param childType 子类对象
	 */
	private void getRecursion(String id,BookType childType){
		//根据ID查询其父类
		BookType parentType = (BookType) sessionFactory.getCurrentSession().get(BookType.class, id);
		//将子类添加进入父类里面
		parentType.getTypes().add(childType);
		map.put(parentType.getId(), parentType);
		String parentid=parentType.getParent()==null?null:parentType.getParent().getId();
		//判断该该父类是否还存在父类
		if(parentid!=null && !parentid.equals("")){
			//如果存在父类首先看看是否已经查询在map集合里面了
			BookType mapType = map.get(parentid);
			if(mapType!=null){
				//如果他的父类已经查询存储在map里面的，这时候只需要将当前的类型作为子类存储在map里面对于的父类
				map.get(parentid).getTypes().add(parentType);
			}else{
				getRecursion(parentid,parentType);
			}
		}else{//如果不存在父类,并将其键添加到keys字符串数组里面
			keys.add(parentType.getId());
		}
	}
	/**
	 * 根据ID来查询当前类别（如果是ID为null表示查询顶级类）
	 * 还需要查询当前类别地下的子类
	 */
	@SuppressWarnings("unchecked")
	public List<BookType> getSelectTypeList(String parentId) {
		String sql;
		List<BookType> list;
		Query query ;
		if(parentId==null ||parentId.equals("")){
			sql="from BookType where parent_id is null";
			query = sessionFactory.getCurrentSession().createQuery(sql);
			list = query.list();
		}else{
			sql="from BookType where parent_id=?";
			query = sessionFactory.getCurrentSession().createQuery(sql);
			list = query.setParameter(0, parentId).list();
			//父类查询，导航需要用到
			parentType(parentId,list);
		}
		//循环查询该类别地下的子类型
		for(BookType type:list){
			sql="from BookType where parent_id=?";
			query = sessionFactory.getCurrentSession().createQuery(sql);
			List<BookType> bookType =  query.setParameter(0, type.getId()).list();
			for(BookType child:bookType){
				type.getTypes().add(child);
			}
		}
		return list;
	}
	//父类查询
	private void parentType(String parentId,List<BookType> list){
		//查询出父类
		BookType parentType = (BookType) sessionFactory.getCurrentSession().get(BookType.class,parentId);
		//给查询出来的每一个子类都设置父类
		for(BookType type:list){
			type.setParent(parentType);
		}
		//将当前父类变成子类
		list=new ArrayList<BookType>();
		list.add(parentType);
		//如果父类还存在父类，就继续查询
		if(parentType.getParent()!=null)
			parentType(parentType.getParent().getId(),list);
	}
	/**
	 * 查询顶级类和子类
	 */
	@SuppressWarnings("unchecked")
	public List<BookType> getAllTypeList(String [] typeid) throws Exception{
		//查询得到顶级类
		String sql="";
		if(typeid==null){
			sql="from BookType where parent_id is null";
		}else{
			sql="from BookType where id in(";
			for(String id:typeid){
				sql+="'"+id+"',";
			}
			sql=sql.substring(0, sql.lastIndexOf(","));
			sql+=")";
		}
		
		List<BookType> list = sessionFactory.getCurrentSession().createQuery(sql).list();
		//查询顶级类的子类
		for(BookType parent:list){
			sql="from BookType where parent_id ='"+parent.getId()+"'";
			List<BookType> childs = sessionFactory.getCurrentSession().createQuery(sql).list();
			parent.getTypes().addAll(childs);
		}
		return list;
	}
	/**低效率方法
	 * 书籍类别查询，只要查询顶级类和子类即可
	 
	@SuppressWarnings("unchecked")
	public List<BookType> getAllTypeList() throws Exception{
		//查询得到顶级类
		String sql="from BookType where parent_id is null";
		Query query = sessionFactory.getCurrentSession().createQuery(sql);
		List<BookType> list = query.list();
		//查询子类，并设置子类的所有子类ID 包括它自己
		for(BookType type:list){
			sql="from BookType where parent_id ='"+type.getId()+"'";
			List<BookType> parents = sessionFactory.getCurrentSession().createQuery(sql).list();
			//查找孙子类
			for(BookType parent:parents){
				getChild(parent);
				//设置ID
				String ids="'"+parent.getId()+"'";
				for(BookType bookType:this.childs){
					ids+=",'"+bookType.getId()+"'";
				}
				parent.setChildid(ids);
				this.childs.clear();
				
			}
			type.getTypes().addAll(parents);
		}
		return list;
	}*/
	/**
	 * 子类递归查询
	 * @param bookType
	 */
	private void getChild(BookType bookType){
		String sql="from BookType where parent_id ='"+bookType.getId()+"'";
		List<BookType> childs = sessionFactory.getCurrentSession().createQuery(sql).list();
		this.childs.addAll(childs);
		for(BookType type:childs){
			getChild(type);
		}
	}
	/**
	 * 获取子类的所以的ID
	 * 'xxxx','xxxx','xxxx'
	 * @param 父类的ID
	 * @return
	 */
	public String getChildId(String parent)throws Exception{
		BookType bookType =(BookType) sessionFactory.getCurrentSession().get(BookType.class, parent);
		getChild(bookType);
		
		String ids="'"+parent+"'";
		for(BookType type:this.childs){
			ids+=",'"+type.getId()+"'";
		}
		this.childs.clear();
		return ids;
	}
	/**
	 * 更新名称和备注
	 */
	public void updateType(BookType bookType) throws Exception {
		String sql ="update BookType set name='"+bookType.getName()+"',remark='"+bookType.getRemark()+"'where id='"+bookType.getId()+"'";
		sessionFactory.getCurrentSession().createSQLQuery(sql).executeUpdate();
	}
	/**
	 * 首页导航
	 */
	public List<BookType> getNavigaction(String[] typeid)throws Exception{
		String where="";
		for(String id:typeid){
			where+="'"+id+"',";
		}
		where=where.substring(0, where.lastIndexOf(","));
		String sql="from BookType where id in("+where+")";
		List<BookType> types = sessionFactory.getCurrentSession().createQuery(sql).list();
		return types;
	}
}
